<script lang="tsx">
import { Vue, Component, ProvideReactive, Watch } from "vue-property-decorator";
import { VNode } from "vue";
import { Axis } from "@/common/utils";
export enum WantTo {
  x_minus = 40,
  x_plus = 38,
  y_minus = 37,
  y_plus = 39,
  z_minus = 189,
  z_plus = 187,
}
// 可接受的code
const assignCode = Object.values(WantTo).filter(
  (item) => typeof item === "number"
);
type RotateConfig = {
  [key in Axis]: number;
};
const getRotateConfigInit = (): RotateConfig => ({
  [Axis.x]: -10,
  [Axis.y]: 30,
  [Axis.z]: 0,
});
@Component({
  name: "KeyCodeCtrl",
})
export default class extends Vue {
  // data
  rotateConfig: RotateConfig = getRotateConfigInit();
  keyCode: number = null;
  timer: number = null;

  // computed
  @ProvideReactive()
  get transformRotate(): string {
    const { rotateConfig } = this;
    return `rotateX(${rotateConfig[Axis.x]}deg) rotateY(${
      rotateConfig[Axis.y]
    }deg) rotateZ(${rotateConfig[Axis.z]}deg)`;
  }

  // methods
  keyDownHandler(e: KeyboardEvent): void {
    const { keyCode } = e;
    // 按了esc键
    if (keyCode === 27) {
      this.rotateConfig = getRotateConfigInit();
      return;
    }
    console.log(47, keyCode);
    if (assignCode.includes(keyCode)) {
      this.keyCode = e.keyCode;
    }
  }
  keyUpHandler(): void {
    this.keyCode = null;
  }
  setTimer(): void {
    this.clearTimer();
    this.timer = setTimeout(() => {
      const { rotateConfig, keyCode } = this;
      const val = WantTo[keyCode];
      const [axis, mark] = val.split("_");
      const axisVal = Axis[axis as unknown as number] as unknown as
        | Axis.x
        | Axis.y
        | Axis.z;
      if (mark === "minus") {
        rotateConfig[axisVal] -= 1;
      } else {
        rotateConfig[axisVal] += 1;
      }
      if (keyCode !== null) {
        this.setTimer();
      }
    }, 16);
  }
  clearTimer(): void {
    clearTimeout(this.timer);
  }

  // 生命周期
  mounted(): void {
    document.addEventListener("keydown", this.keyDownHandler, true);
    document.addEventListener("keyup", this.keyUpHandler, true);
  }
  beforeDestroy(): void {
    document.removeEventListener("keydown", this.keyDownHandler, true);
    document.removeEventListener("keyup", this.keyUpHandler, true);
    this.clearTimer();
  }
  render(): VNode[] {
    return this.$slots.default;
  }

  // watch
  @Watch("keyCode")
  onKeyCodeChange(n: number): void {
    if (n) {
      this.setTimer();
    } else {
      this.clearTimer();
    }
  }
}
</script>
